Hi, 大家好!
繼昨天的研究,我們昨天研究了CollectionProxy 涉及到的Reflection 大概是什麼,今天則想繼續研究CollectionProxy 的方法,和稍微探討一下繼承自Relation 的東東:
不過先回到CollectionProxy 上方的定義,這句話一直令我有點疑惑:
This class delegates unknown methods to @target via method_missing.
翻譯蒟蒻:CollectionProxy 類別透過method_missing 來代表target 的unknown methods
但這根本沒翻譯吧,到底是什麼意思呢?XD
先來找找method_missing
,神奇的是他居然真的是個方法!
method_missing(method, *args, &block)Link
:
Allows access to the object attributes, which are held in the hash returned by attributes, as though they were first-class methods. So a Person class with a name attribute can for example use Person#name and Person#name= and never directly use the attributes hash – except for multiple assignments with ActiveRecord::Base#attributes=.
*翻譯蒟蒻:該方法可確保能存取物件的attributes,後面太難了先略過
It's also possible to instantiate related objects, so a Client class belonging to the clients table with a master_id foreign key can instantiate master through Client#master.
再看到這句話,大概就能承接回我們已知的結果:User.first.posts
回傳的CollectionProxy,會透過method_missing
檢查/存取目標Post 的attributes,而該方法也能透過foreign key(posts 上的userId)來實體化物件
燈楞~~ 這好像跟上篇的結果相當,這就也就是為何我們可以透過User.first.posts.create(title: "IThome", body: "IThome rocks")
來建立Post 了吧!?
最後我想了解的是這句話:
CollectionProxy is computed directly through SQL and does not trigger by itself the instantiation of the actual post records.
但我們先來看看CollectionProxy 的類別方法,個人覺得最有用的是reload
:
如當我這麼做的時候:
posts = User.first.posts
# 我們可以針對loaded 起來的CollectionProxy(posts) update、clear 等:
posts.map { |post| post.update(body: "IThome blablablaaaa") }
posts.clear # 小心使用 XD
甚至能直接reload 或reset,而不需要重新reload 整個 Post(posts table),這大概也能解釋為什麼CollectionProxy 是很妙用的類別:
posts.reload
posts.reset
那does not trigger by itself the instantiation of the actual post records
又要怎麼理解呢?
個人的想法是如User.first.posts.create(title: "IThome", body: "IThome rocks")
:
我們可以透過CollectionProxy loaded 起來的reflection 內含有的資訊,直接透過SQL 將這筆資料建立,而不需要從Post.create(userId: 1
, title: "IThome", body: "IThome rocks") 等重新實體化一筆紀錄...?
嗯,不確定,邊研究再看看如何驗證自己的想法囉~~
那今天的研究就到這邊結束,謝謝大家~